using Asp.Versioning;
using Microsoft.AspNetCore.Cors;
using Microsoft.OpenApi.Models;
using Shared.Caching.FreeRedis;
using UserService.Application;
using UserService.HttpApi.Host.Filter;
using UserService.SqlSugarCore;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.Swashbuckle;

namespace UserService.HttpApi.Host;

[DependsOn(
    typeof(AbpAutofacModule), // 使用Autofac作为DI容器
    typeof(AbpAspNetCoreMvcModule), // ASP.NET Core MVC模块
    typeof(AbpAspNetCoreSerilogModule), // Serilog日志模块
    typeof(AbpSwashbuckleModule), // Swagger文档模块
    typeof(FreeRedisCacheModule), // 自定义FreeRedis缓存模块
    typeof(UserServiceApplicationModule), // 用户服务应用层模块
    typeof(UserServiceSqlSugarCoreModule)
)]
public class UserServiceHttpApiHostModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var configuration = context.Services.GetConfiguration();

        // 配置跨域
        ConfigureCors(context, configuration);

        // 配置Swagger
        ConfigureSwaggerServices(context, configuration);

        // 配置FreeRedis缓存
        ConfigureFreeRedisCache(context, configuration);

        // 配置ABP动态Controller API
        ConfigureConventionalControllers(context);
    }

    /// <summary>
    /// 配置跨域策略
    /// </summary>
    private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddCors(options =>
        {
            options.AddDefaultPolicy(builder =>
            {
                builder
                    .WithOrigins(
                        configuration["App:CorsOrigins"]
                            .Split(",")
                            .Select(o => o.Trim())
                            .ToArray()
                    )
                    .WithAbpExposedHeaders()
                    .SetIsOriginAllowedToAllowWildcardSubdomains()
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
            });
        });
    }

    /// <summary>
    /// 配置Swagger文档
    /// </summary>
    private void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddAbpSwaggerGen(
            options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo { Title = "UserAggregateRoot Service API", Version = "v1" });
                options.DocInclusionPredicate((docName, description) => true);
                options.CustomSchemaIds(type => type.FullName);
                
                // 配置 JWT 认证
                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme.",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer",
                    BearerFormat = "JWT"
                });
                
                options.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
                        },
                        Array.Empty<string>()
                    }
                });
                
                // 添加过滤器隐藏ABP内部API
                options.DocumentFilter<HideAbpEndpointsDocumentFilter>();
            });
    }

    /// <summary>
    /// 配置FreeRedis缓存
    /// </summary>
    private void ConfigureFreeRedisCache(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.Configure<FreeRedisCacheOptions>(options =>
        {
            options.ConnectionString = configuration["Redis:ConnectionString"];
            options.DefaultExpireSeconds = 3600; // 1小时
        });
    }

    /// <summary>
    /// 配置ABP动态Controller API
    /// </summary>
    private void ConfigureConventionalControllers(ServiceConfigurationContext context)
    {
        context.Services.AddAbpApiVersioning(options =>
        {
            options.ReportApiVersions = true;
            options.AssumeDefaultVersionWhenUnspecified = true;
            options.DefaultApiVersion = new ApiVersion(1, 0);
        });

        // 设置动态API控制器
        Configure<AbpAspNetCoreMvcOptions>(options =>
        {
            options.ConventionalControllers.Create(typeof(UserServiceApplicationModule).Assembly, opts =>
            {
                opts.RootPath = "user-service";
                opts.RemoteServiceName = "UserAggregateRoot";
            });
        });
    }

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
        var env = context.GetEnvironment();

        // 开发环境错误页
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        // 使用HTTPS重定向
        app.UseHttpsRedirection();

        // 使用静态文件
        app.UseStaticFiles();

        // 使用路由
        app.UseRouting();

        // 使用跨域
        app.UseCors();

        // 使用认证
        app.UseAuthentication();

        // 使用授权
        app.UseAuthorization();

        // 使用ABP请求本地化
        app.UseAbpRequestLocalization();

        // 使用Swagger
        app.UseSwagger();
        app.UseAbpSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "UserAggregateRoot Service");
            options.DocumentTitle = "UserAggregateRoot Documentation";
        });

        // 使用审计日志
        app.UseAuditing();

        // 使用ABP多租户日志记录
        //app.UseAbpSerilogEnrichers();

        // 配置端点
        app.UseConfiguredEndpoints();
    }
}